package com.gitee.apanlh.util.algorithm.encrypt.symmetric;

import com.gitee.apanlh.util.algorithm.KeyUtils;
import com.gitee.apanlh.util.valid.Assert;

/**
 * 	PBE（Password-Based Encryption基于密码的加密）类继承自BouncyCastleSymmetricAbstract
 * 	<br>提供了使用基于密码的加密算法进行对称加密和解密的功能
 * 	<br>在默认情况下，会使用一个随机的128位密码和一个随机的128位盐值，并使用默认的迭代次数100，以及PBEWITHSHAAND128BITAES-CBC-BC算法
 * 	<br>想要获取初始化密钥或者盐值请使用{@link #getPassword()}、{@link #getSalt()}
 * 	<p>支持多种PBE算法:{@link PBEAlgorithms}
 * 
 * 	<p>示例用法：
 * 	<pre>PBE pbe = new PBE(KeyUtils.generate64(), KeyUtils.generate64(), PBEAlgorithms.MD5_DES);</pre>
 *  <pre>PBE pbe2 = PBE.create();</pre>
 * 	@author Pan
 */
public class PBE extends BouncyCastleSymmetricAbstract {
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>随机128位密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 */
	public PBE() {
		super(KeyUtils.generate128(), KeyUtils.generate128(), 100, PBEAlgorithms.SHA_128_AES_CBC);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>随机128位密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(PBEAlgorithms pbeAlgorithms) {
		super(KeyUtils.generate128(), KeyUtils.generate128(), 100, pbeAlgorithms);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 */
	public PBE(byte[] password) {
		this(password, PBEAlgorithms.SHA_128_AES_CBC);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(byte[] password, PBEAlgorithms pbeAlgorithms) {
		super(password, KeyUtils.generate128(), 100, pbeAlgorithms);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 */
	public PBE(byte[] password, byte[] salt) {
		super(password, salt, 100, PBEAlgorithms.SHA_128_AES_CBC);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(byte[] password, byte[] salt, PBEAlgorithms pbeAlgorithms) {
		super(password, salt, 100, pbeAlgorithms);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>自定义迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	count			迭代次数
	 */
	public PBE(byte[] password, byte[] salt, int count) {
		super(password, salt, count, PBEAlgorithms.SHA_128_AES_CBC);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>自定义迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(byte[] password, byte[] salt, int count, PBEAlgorithms pbeAlgorithms) {
		super(password, salt, count, pbeAlgorithms);
	}

	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(byte[] password, int count, PBEAlgorithms pbeAlgorithms) {
		super(password, KeyUtils.generate128(), count, pbeAlgorithms);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>默认128位密码
	 * 	<br>默认128位盐值
	 * 	<br>自定义迭代次数
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	count			迭代次数
	 */
	public PBE(int count) {
		super(KeyUtils.generate128(), KeyUtils.generate128(), count, PBEAlgorithms.SHA_128_AES_CBC);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>默认128位密码
	 * 	<br>默认128位盐值
	 * 	<br>自定义迭代次数
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(int count, PBEAlgorithms pbeAlgorithms) {
		super(KeyUtils.generate128(), KeyUtils.generate128(), count, pbeAlgorithms);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 */
	public PBE(String password) {
		this(password.getBytes(), PBEAlgorithms.SHA_128_AES_CBC);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(String password, PBEAlgorithms pbeAlgorithms) {
		super(password.getBytes(), KeyUtils.generate128(), 100, pbeAlgorithms);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 */
	public PBE(String password, String salt) {
		super(password.getBytes(), salt.getBytes(), 100, PBEAlgorithms.SHA_128_AES_CBC);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(String password, String salt, PBEAlgorithms pbeAlgorithms) {
		super(password.getBytes(), salt.getBytes(), 100, pbeAlgorithms);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>自定义迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	count			迭代次数
	 */
	public PBE(String password, String salt, int count) {
		super(password.getBytes(), salt.getBytes(), count, PBEAlgorithms.SHA_128_AES_CBC);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>自定义迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(String password, String salt, int count, PBEAlgorithms pbeAlgorithms) {
		super(password.getBytes(), salt.getBytes(), count, pbeAlgorithms);
	}
	
	/**	
	 * 	构造函数-初始化构造PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 */
	public PBE(String password, int count, PBEAlgorithms pbeAlgorithms) {
		super(password.getBytes(), KeyUtils.generate128(), count, pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>随机128位密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@return	PBE
	 */
	public static PBE create() {
		return new PBE();
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>随机128位密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(PBEAlgorithms pbeAlgorithms) {
		return new PBE(pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@return	PBE
	 */
	public static PBE create(byte[] password) {
		return new PBE(password);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(byte[] password, PBEAlgorithms pbeAlgorithms) {
		return new PBE(password, pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@return	PBE
	 */
	public static PBE create(byte[] password, byte[] salt) {
		return new PBE(password, salt);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(byte[] password, byte[] salt, PBEAlgorithms pbeAlgorithms) {
		return new PBE(password, salt, pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>自定义迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	count			迭代次数
	 * 	@return	PBE
	 */
	public static PBE create(byte[] password, byte[] salt, int count) {
		return new PBE(password, salt, count);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>自定义迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(byte[] password, byte[] salt, int count, PBEAlgorithms pbeAlgorithms) {
		return new PBE(password, salt, count, pbeAlgorithms);
	}

	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(byte[] password, int count, PBEAlgorithms pbeAlgorithms) {
		return new PBE(password, count, pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>默认128位密码
	 * 	<br>默认128位盐值
	 * 	<br>自定义迭代次数
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	count			迭代次数
	 * 	@return	PBE
	 */
	public static PBE create(int count) {
		return new PBE(count);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>默认128位密码
	 * 	<br>默认128位盐值
	 * 	<br>自定义迭代次数
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(int count, PBEAlgorithms pbeAlgorithms) {
		return new PBE(count, pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@return	PBE
	 */
	public static PBE create(String password) {
		Assert.isNotEmpty(password);
		return new PBE(password);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>随机128位盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(String password, PBEAlgorithms pbeAlgorithms) {
		Assert.isNotEmpty(password);
		return new PBE(password, pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@return	PBE
	 */
	public static PBE create(String password, String salt) {
		Assert.isNotEmpty(password);
		Assert.isNotEmpty(salt);
		return new PBE(password, salt);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(String password, String salt, PBEAlgorithms pbeAlgorithms) {
		Assert.isNotEmpty(password);
		Assert.isNotEmpty(salt);
		return new PBE(password, salt, pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>自定义迭代100次
	 * 	<br>默认PBEWITHSHAAND128BITAES-CBC-BC算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	count			迭代次数
	 * 	@return	PBE
	 */
	public static PBE create(String password, String salt, int count) {
		Assert.isNotEmpty(password);
		Assert.isNotEmpty(salt);
		return new PBE(password, salt, count);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>自定义迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	salt			盐值
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(String password, String salt, int count, PBEAlgorithms pbeAlgorithms) {
		Assert.isNotEmpty(password);
		Assert.isNotEmpty(salt);
		return new PBE(password, salt, count, pbeAlgorithms);
	}
	
	/**	
	 * 	创建PBE
	 * 	<br>自定义密码
	 * 	<br>自定义盐值
	 * 	<br>默认迭代100次
	 * 	<br>自定义PBE算法
	 * 	
	 * 	@author Pan
	 * 	@param 	password		密码
	 * 	@param 	count			迭代次数
	 * 	@param 	pbeAlgorithms	对称加密算法类型
	 * 	@return	PBE
	 */
	public static PBE create(String password, int count, PBEAlgorithms pbeAlgorithms) {
		Assert.isNotEmpty(password);
		return new PBE(password, count, pbeAlgorithms);
	}
}
